﻿using Shop.Model.DB;
using Shop.Model.Goods;
using Shop.RemoteModel;
using Shop.RemoteModel.SpuGoods.Model;
using Shop.Repository;
using WeDonekRpc.Helper;
using WeDonekRpc.Model;

namespace Shop.Collect.lmpl
{
    internal class GoodsCollect : IGoodsCollect
    {
        private readonly IGoodsRepository _Repository;

        public GoodsCollect ( IGoodsRepository repository )
        {
            this._Repository = repository;
        }

        public long Add ( GoodsSetArg arg )
        {
            if ( this._Repository.IsExist(c => c.GoodsName == arg.GoodsName) )
            {
                throw new ErrorException("shop.goods.name.repeat");
            }
            else if ( this._Repository.IsExist(c => c.GoodsSpu == arg.GoodsSpu) )
            {
                throw new ErrorException("shop.goods.spu.repeat");
            }
            return this._Repository.Add(arg);
        }
        public void Delete ( DBGoods goods )
        {
            if ( goods.IsDrop )
            {
                throw new ErrorException("shop.goods.already.delete");
            }
            else if ( goods.Status == GoodsStatus.发布中 )
            {
                throw new ErrorException("shop.goods.already.pulic");
            }
            else if ( goods.Status == GoodsStatus.起草 )
            {
                this._Repository.Delete(goods.Id);
            }
            else
            {
                this._Repository.Drop(goods.Id);
            }
        }
        public DBGoods Get ( long id )
        {
            return this._Repository.Get(id);
        }
        public Result Get<Result> ( long id ) where Result : class
        {
            return this._Repository.Get<Result>(id);
        }
        public Result[] Gets<Result> ( long[] ids ) where Result : class, new()
        {
            return this._Repository.Gets<Result>(ids);
        }

        public Dictionary<long, string> GetNames ( long[] ids )
        {
            return this._Repository.Gets(ids, a => new
            {
                a.Id,
                a.GoodsName
            }).ToDictionary(a => a.Id, a => a.GoodsName);
        }
        public Result[] GetTops<Result> ( TopGetArg arg ) where Result : class, new()
        {
            return _Repository.GetTops<Result>(arg);
        }
        public Dictionary<long, GoodsState> GetState ( long[] ids )
        {
            return this._Repository.Gets(ids, a => new
            {
                a.Id,
                a.GoodsName,
                a.Status
            }).ToDictionary(a => a.Id, a => new GoodsState
            {
                Status = a.Status,
                GoodsName = a.GoodsName,
            });
        }
        public void OffShelf ( DBGoods goods )
        {
            if ( goods.Status == GoodsStatus.下架 )
            {
                return;
            }
            this._Repository.Offshelf(goods.Id);
        }

        public bool Public ( DBGoods goods, short num, decimal price )
        {
            if ( goods.Status == GoodsStatus.发布中 || goods.Status == GoodsStatus.已发布 )
            {
                return false;
            }
            this._Repository.Public(goods.Id, num, price);
            return true;
        }

        public void PublicComplete ( long id )
        {
            this._Repository.PublicComplete(id);
        }

        public Result[] Query<Result> ( GoodsQuery query, IBasicPage paging, out int count ) where Result : class
        {
            return this._Repository.Query<Result>(query, paging, out count);
        }
        public bool Set ( DBGoods goods, GoodsSetArg arg )
        {
            if ( goods.GoodsName != arg.GoodsName && this._Repository.IsExist(c => c.GoodsName == arg.GoodsName) )
            {
                throw new ErrorException("shop.goods.name.repeat");
            }
            else if ( goods.GoodsSpu != arg.GoodsSpu && this._Repository.IsExist(c => c.GoodsSpu == arg.GoodsSpu) )
            {
                throw new ErrorException("shop.goods.spu.repeat");
            }
            return this._Repository.Update(goods, arg);
        }
    }
}
